package server.threads;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import server.GameClientInfo;
import server.LobbyServer;
import server.beans.MessageBean;
import server.constants.IncomingConstants;
import server.constants.OutgoingConstants;

/**
 * This thread is used by a LobbyServer to handle any actions a user can make
 * from the lobby. Each user is mapped to one LobbyServerThread and actions
 * that can be made include creating a game, joining an existing game, and
 * refreshing the list of available games.
 */
public class LobbyServerThread extends Thread {
	private GameClientInfo client;
	
	private BufferedReader in;
   	private PrintWriter out;
	
	public LobbyServerThread(GameClientInfo client) {
		this.client = client;
		
		try {
			out = new PrintWriter(client.getSocket().getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(client.getSocket().getInputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void run() {
		String incomingMsg = "";
		String outgoingMsg = "";

		try {
			while((incomingMsg = in.readLine()) != null){
				System.out.println("LobbyServer received: \"" + incomingMsg + "\" from " + client.getSocket().getInetAddress() + ":" + client.getSocket().getPort());
				
				// Parse the json message to obtain the message type 
				Gson gson = new Gson();
		        MessageBean bean = gson.fromJson(incomingMsg, MessageBean.class);

				if(bean.getType() == IncomingConstants.USERNAME) {
					client.setName(bean.getGameDetails().getName());
					outgoingMsg = "{\"type\":" + OutgoingConstants.USERNAME_SUCCESSFUL + "}";
				}
				else if(bean.getType() == IncomingConstants.CREATE) {
					boolean createSuccessful = LobbyServer.getInstance().createGame(bean.getGameDetails().getName(), client, bean.getGameDetails().getPassword(), bean.getGameDetails().getTimeLimit(), bean.getGameDetails().getScoreLimit());
					if(createSuccessful) {
						outgoingMsg = "{\"type\":" + OutgoingConstants.CREATE_SUCCESSFUL + "}";
						out.println(outgoingMsg);
						System.out.println("LobbyServer sent: \"" + outgoingMsg + "\"");
						break;
					}
					else
						outgoingMsg = "{\"type\":" + OutgoingConstants.CREATE_UNSUCCESFUL + "}";
				}
				else if(bean.getType() == IncomingConstants.JOIN) {
					int joinStatus = LobbyServer.getInstance().joinGame(bean.getGameDetails().getName(), client, bean.getGameDetails().getPassword());
					if(joinStatus == LobbyServer.NO_GAME_EXISTS) {
						outgoingMsg = "{\"type\":" + OutgoingConstants.NO_GAME_EXISTS + "}";
					}
					else if(joinStatus == LobbyServer.GAME_FULL) {
						outgoingMsg = "{\"type\":" + OutgoingConstants.GAME_FULL + "}";
					}
					else if(joinStatus == LobbyServer.WRONG_PASSWORD) {
						outgoingMsg = "{\"type\":" + OutgoingConstants.WRONG_PASSWORD + "}";
					}
					else if(joinStatus == LobbyServer.JOIN_SUCCESSFUL) {
						outgoingMsg = "{\"type\":" + OutgoingConstants.JOIN_SUCCESSFUL + "}";
						out.println(outgoingMsg);
						System.out.println("LobbyServer sent: \"" + outgoingMsg + "\"");
						break;
					}					
				}
				else if(bean.getType() == IncomingConstants.REFRESH) {
					outgoingMsg = "{\"type\":" + OutgoingConstants.REFRESH_GAMESERVERS + ",\"gameServers\":" + LobbyServer.getInstance().toJson() + "}";
				}
				else {
					outgoingMsg = "{\"type\":" + OutgoingConstants.INVALID_MESSAGE + "}";
				}
				
				out.println(outgoingMsg);
				System.out.println("LobbyServer sent: \"" + outgoingMsg + "\"");
			}
		} catch (IOException e) {
			// Player has shut down the application and left the lobby
			System.out.println(client.getName() + " has left the lobby.");
		} catch (JsonSyntaxException e) {
			System.out.println("Error: JSON Message could not be parsed");
		}
	}
}
